/*
 * TowerYellowThree.java
 *
 * Created on December 15, 2007, 1:37 PM
 *
 * Copyright (C) 2007-2008  Hylke van der Schaaf
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, in version 3 of the License.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package hextd.tower;

import hextd.Constants;
import hextd.creep.HexTDCreep;
import hextd.util.Geometry;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * @author hylke
 */
public class TowerYellowThree extends TowerBase {

	public static final Map<String, Long> price = new HashMap<String, Long>();

	static {
		price.put(Constants.RESOURCE_CREDIT, 2000000l);
	}
	public static int damage = 32000000;
	public static double range = 9f;
	public static String name = "Yellow Three";
	//
	private HexTDCreep fireAt = null;
	private Constants.COLOR damageColor = Constants.COLOR.YELLOW;
	private int charge = 0;
	private int chargeMax = 81;
	//
	private Color transColor;
	private Stroke[] beam1Strokes;
	private Stroke[] beam2Strokes;
	private Stroke beam1Stroke;
	private Stroke beam2Stroke;
	private Color beam1Color;
	private Color beam2Color;
	private Shape[] pies;
	private Color line2Color;
	private Point2D.Double tempTargetPLoc = new Point2D.Double();

	/** Creates a new instance of TowerYellowThree */
	public TowerYellowThree() {
		super(FactoryTower.type.yellowThree, price, damage, range);
		lineColor = new Color(220, 220, 0);
		line2Color = new Color(110, 110, 0);
		transColor = new Color(lineColor.getRed(), lineColor.getGreen(), lineColor.getBlue(), 100);
		beam1Color = new Color(lineColor.getRed(), lineColor.getGreen(), lineColor.getBlue(), 100);
		beam2Color = new Color(255, 255, 128);
		hexInfluence = 3;
	}

	public boolean aquireTarget() {
		if (!lock) {
			fireAt = null;
		}
		HexTDCreep enemy = findEnemy(fireAt, false);
		fireAt = enemy;
		return (enemy != null);
	}

	@Override
	public void runTick(int gameTime) {
		if (fireAt == null || charge == 0) {
			if (charge > 0) {
				charge--;
			}
			if (aquireTarget()) {
				charge += 2;
			}
		}

		if (fireAt != null) {
			// Still a valid target?
			if (fireAt.isValidTarget()) {
				charge += 2;
				if (charge >= chargeMax - 1) {
					fireAt.doDamage(getOwner(), damageCurrent, damageColor);
					charge = 0;
				} else {
					if (beam1Strokes != null) {
						beam1Stroke = beam1Strokes[charge - 1];
						beam2Stroke = beam2Strokes[charge - 1];
					}
				}
			} else {
				charge *= 0.9;
				fireAt = null;
			}
		}
	}

	@Override
	public String getStatusString() {
		String retString = "";
		retString += "<h1>Yellow Tower 3</h1>"
				+ "<p>"
				+ "<b>Level:</b> " + (1 + level) + "<br>\n"
				+ "<b>Damage:</b> " + damageText + "<br>\n"
				+ "<b>Range:</b> " + rangeText + "<br>"
				+ "</p>\n";
		return retString;
	}

	@Override
	public String getDescription() {
		String retString = "";
		retString += "<h1>Yellow Tower 3</h1>"
				+ "<p>"
				+ "Like yellow tower 2, but if the target is destroyed before firing, only 10% of the charge is lost. "
				+ "When there is no target available the charge will gradually drop to zero."
				+ "<br>Strong against yellow enemies, very weak against blue enemies."
				+ "</p>"
				+ "<p>"
				+ "<b>Price:</b> " + TowerYellowThree.form.format(TowerYellowThree.price) + "<br>"
				+ "<b>Damage:</b> " + TowerYellowThree.form.format(damageCurrent) + "<br>"
				+ "<b>Range:</b> " + TowerYellowThree.form.format(rangeCurrent) + "<br>"
				+ "<b>Refire rate:</b> 0.5/s"
				+ "</p>";
		return retString;
	}

	@Override
	protected void generateShapes() {
		double scale2 = 0.5 * paintScale;
		int shapeCount = 8;

		shapes = new Shape[shapeCount];

		double[][] points2 = Geometry.createHexCoords(paintScale);
		GeneralPath polyHex = Geometry.coordsToGeneralPath(points2, true);

		Area tower = new Area(polyHex);

		double[][] points1 = Geometry.createHexCoords(scale2);
		polyHex = Geometry.coordsToGeneralPath(points1, true);
		Area tempArea = new Area(polyHex);

		tower.subtract(tempArea);
		shapes[0] = tower;
		shapes[1] = new Ellipse2D.Double(-1.0 * strokeScale, -1.0 * strokeScale, 2.0 * strokeScale, 2.0 * strokeScale);
		shapes[2] = new Line2D.Double(points1[0][0], points1[0][1], points2[0][0], points2[0][1]);
		shapes[3] = new Line2D.Double(points1[3][0], points1[3][1], points2[3][0], points2[3][1]);

		shapes[4] = new Line2D.Double(0, 0, points1[1][0], points1[1][1]);
		shapes[5] = new Line2D.Double(0, 0, points1[2][0], points1[2][1]);
		shapes[6] = new Line2D.Double(0, 0, points1[4][0], points1[4][1]);
		shapes[7] = new Line2D.Double(0, 0, points1[5][0], points1[5][1]);

		shapeAction = new int[shapeCount];
		shapeAction[0] = 2;

		shapeColor = new Color[shapeCount];
		shapeColor[0] = lineColor;

		strokes = new Stroke[shapeCount];
		strokes[0] = new BasicStroke(2.0f * strokeScale, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);

		float max = chargeMax;
		pies = new Shape[chargeMax + 1];
		for (int i = 0; i < pies.length; i++) {
			pies[i] = new Arc2D.Double(-scale2, -scale2, scale2 * 2, scale2 * 2, 0, 360 * i / (max - 1), Arc2D.PIE);
		}

		beam1Strokes = new Stroke[chargeMax];
		beam2Strokes = new Stroke[chargeMax];
		for (int i = 0; i < chargeMax; i++) {
			beam1Strokes[i] = new BasicStroke(6.0f * i / max * strokeScale, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
			beam2Strokes[i] = new BasicStroke(3.0f * i / max * strokeScale, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
		}
	}

	@Override
	public void paint(Graphics2D g2, int gameTime) {
		Stroke defaultStroke = g2.getStroke();
		AffineTransform saveXform = g2.getTransform();

		g2.transform(atTranslate);

		g2.setColor(lineColor);
		g2.setStroke(strokes[0]);
		g2.fill(pies[charge]);

		g2.setColor(line2Color);
		g2.fill(shapes[0]);

		g2.setColor(lineColor);
		g2.draw(shapes[0]);
		g2.draw(shapes[1]);
		g2.draw(shapes[2]);
		g2.draw(shapes[3]);
		g2.draw(shapes[4]);
		g2.draw(shapes[5]);
		g2.draw(shapes[6]);
		g2.draw(shapes[7]);

		g2.setFont(levelFont);
		g2.drawString("" + (level + 1), levelLocation[0], levelLocation[1]);

		super.paintQueue(g2, gameTime);

		if (selected) {
			g2.setColor(rangeColor);
			g2.draw(rangeCircle);
		}

		g2.setTransform(saveXform);
		g2.setStroke(defaultStroke);

	}

	@Override
	public void paintEffects(Graphics2D g2, int gameTime) {
		Stroke defaultStroke = g2.getStroke();
		HexTDCreep target = fireAt;
		if (target != null && charge > 0) {
			target.getPaintLocation(tempTargetPLoc);
			g2.setColor(beam1Color);
			g2.setStroke(beam1Stroke);
			g2.draw(new Line2D.Double(paintLocation.x, paintLocation.y, tempTargetPLoc.x, tempTargetPLoc.y));
			g2.setColor(beam2Color);
			g2.setStroke(beam2Stroke);
			g2.draw(new Line2D.Double(paintLocation.x, paintLocation.y, tempTargetPLoc.x, tempTargetPLoc.y));
		}

		g2.setStroke(defaultStroke);
	}
}
